package com.mzx.javase.thread.deadlock;

/**
 * 类描述：模拟死锁
 * 死锁的概念？两个线程对象，线程A持有资源2，线程B持有资源1，他们都想同时申请对方的资源，所以这两个线程都会互相等待而进入死锁状态
 * 如何避免死锁？
 * 两个线程尽量去竞争同一个资源，这样可以避免不同线程的资源互相占有
 *
 * @ClassName DeadLockDemo
 * @Description TODO
 * @Author 马子鑫
 * @Date 2022/8/6 16:22
 * @Version 1.0
 */
public class DeadLockDemo {
    private static Object lock1 = new Object();
    private static Object lock2 = new Object();
    public static void main(String[] args) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized (lock2) {
                    System.out.println(Thread.currentThread().getName() + "拿到了对象锁2");
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                    System.out.println(Thread.currentThread().getName() + "等待锁1");
                    synchronized (lock1){
                        System.out.println(Thread.currentThread().getName() + "拿到了锁1");
                    }
                }
            }
        }, "线程A").start();
        //产生死锁的线程写法
//        new Thread(new Runnable() {
//            @Override
//            public void run() {
//                synchronized (lock1){
//                    System.out.println(Thread.currentThread().getName() + "拿到了锁1");
//                    try {
//                        Thread.sleep(1000);
//                    } catch (InterruptedException e) {
//                        throw new RuntimeException(e);
//                    }
//                    System.out.println(Thread.currentThread().getName() + "等待锁2");
//                    synchronized (lock2){
//                        System.out.println(Thread.currentThread().getName() + "拿到了锁2");
//                    }
//                }
//            }
//        }, "线程B").start();

        //破解死锁的线程2
        new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized (lock2) {
                    System.out.println(Thread.currentThread().getName() + "拿到了锁2");
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                    System.out.println(Thread.currentThread().getName() + "等待锁1");
                    synchronized (lock1) {
                        System.out.println(Thread.currentThread().getName() + "拿到锁1");
                    }
                }
            }
        },"线程B").start();

    }
}
